/**
 * \class ExpRegistry.h /GenProg/Helpers/ExpRegistry.h
 *
 *  \date 16 maj 2012
 *  \author calle
 *  
 *  \brief Registry to keep functions to create expressions
 *
 *
 */

#ifndef EXPREGISTRY_H_
#define EXPREGISTRY_H_
#include <map>
#include <Generator/TerminalState.h>
#include <boost/shared_ptr.hpp>
#include <AbsSyn/GenExpClasses/ExpressionType.h>

class IGenExp;

/*
 *
 */
using namespace std;
class ExpRegistry {
public:
	/**
	 * \brief Shared pointer for Expression generation
	 */
	typedef boost::shared_ptr<IGenExp> TGenPtr;
	/**
	 * \brief Type definition of a return map
	 *
	 * The map return will consists of types and generator objects
	 */
	typedef map< ExpressionType , TGenPtr > TGenFunTypeMap;
private:


	/**
	 * \brief Map for Terminal state and expression generation
	 *
	 * This is where all  expressions are stored.
	 */
	typedef map< TerminalState,TGenFunTypeMap> TStateMap;
	TStateMap m_GenFunMap;

public:



	ExpRegistry();
	virtual ~ExpRegistry();

	/**
	 * \brief generation object for expressions.
	 *
	 * @TODO Need to update the  documentation for this
	 *
	 * For the Generators to be able to use the expressions available
	 * this registry stores an generation object to be able generate new expression of
	 * TerminalState kind. No one else knows how to generate a new
	 * Expression as good as the expression it self.
	 *
	 * \see TerminalState
	 * \see AbsSyn::creationalFunc
	 * \see AbsSyn
	 *
	 * \param[in] TerminalState for the function provided
	 * \param[in] Generation object.
	 * \return True if the object is added otherwise false
	 */
	bool addGenFun(TerminalState state,ExpressionType expType,TGenPtr genObj);

	/**
	 * \brief Gets all the available generation methods for some specific
	 * TerminalState
	 *
	 * @see TGenFunTypeMap
	 * @see ExpressionType
	 *
	 *  \param[in/out] TGenFunTypeMap - inhibits all the methods together with the
	 *  expression type in a map.
	 *  \return True if there exists object
	 */
	bool getAll(TerminalState state,TGenFunTypeMap& outMap) const;
};

#endif /* EXPREGISTRY_H_ */
